import { isNil, isUndefined, isFunction, isObject, trimStart, mapValues, omitBy, extend } from "lodash";
import qs from "query-string";
import { createBrowserHistory } from "history";
import { policy } from "@/services/policy";

const history = createBrowserHistory();

function normalizeLocation(rawLocation) {
  const { pathname, search, hash } = rawLocation;
  const result = {};

  result.path = pathname;
  result.search = mapValues(qs.parse(search), value => (isNil(value) ? true : value));
  result.hash = trimStart(hash, "#");
  result.url = `${pathname}${search}${hash}`;

  return result;
}

const location = {
  //设置样式默认颜色
  initStyleColor(colorStyle) {
    if (colorStyle === "light") {
      localStorage.removeItem('colorstyle_mode');
      localStorage.removeItem('colorstyle_bg');
      localStorage.removeItem('colorstyle_back');
      localStorage.removeItem('colorstyle_color');
      localStorage.removeItem('colorstyle_titleback');
      localStorage.removeItem('colorstyle_titlecolor');
      localStorage.removeItem('colorstyle_dialogback');
    } else {
      localStorage.setItem('colorstyle_mode',colorStyle);
      
      const modes = policy.getDefaultStyles() && policy.getDefaultStyles().filter(item => item.key === colorStyle);      
      if (modes && modes.length > 0) {
        const {colors} = modes[0];
        if (colors) {
          localStorage.setItem('colorstyle_bg', colors[0]);
          localStorage.setItem('colorstyle_back', colors[1]);
          localStorage.setItem('colorstyle_color', colors[2]);
          localStorage.setItem('colorstyle_titleback', colors[3]);
          localStorage.setItem('colorstyle_titlecolor', colors[4]);
          localStorage.setItem('colorstyle_dialogback', colors[5]);
        }
      }
    }
  },

  //设置本地样式默认颜色
  initStyleColorLocal(colorStyle, fixColors=[]) {
    if (colorStyle === "light") {
      localStorage.removeItem('colorstyle_mode_local');
      localStorage.removeItem('colorstyle_bg_local');
      localStorage.removeItem('colorstyle_back_local');
      localStorage.removeItem('colorstyle_color_local');
      localStorage.removeItem('colorstyle_titleback_local');
      localStorage.removeItem('colorstyle_titlecolor_local');
      localStorage.removeItem('colorstyle_dialogback_local');
    } else {
      localStorage.setItem('colorstyle_mode_local',colorStyle);

      if (fixColors.length > 0) {
        localStorage.setItem('colorstyle_bg_local', fixColors[0]);
        localStorage.setItem('colorstyle_back_local', fixColors[1]);
        localStorage.setItem('colorstyle_color_local', fixColors[2]);
        localStorage.setItem('colorstyle_titleback_local', fixColors[3]);
        localStorage.setItem('colorstyle_titlecolor_local', fixColors[4]);
        localStorage.setItem('colorstyle_dialogback_local', fixColors[5]);
      } else {
        const modes = policy.getDefaultStyles() && policy.getDefaultStyles().filter(item => item.key === colorStyle);            
        if (modes && modes.length > 0) {
          const {colors} = modes[0];
          if (colors) {
            localStorage.setItem('colorstyle_bg_local', colors[0]);
            localStorage.setItem('colorstyle_back_local', colors[1]);
            localStorage.setItem('colorstyle_color_local', colors[2]);
            localStorage.setItem('colorstyle_titleback_local', colors[3]);
            localStorage.setItem('colorstyle_titlecolor_local', colors[4]);
            localStorage.setItem('colorstyle_dialogback_local', colors[5]);
          }
        }  
      }
    }
  },

  //还原本地样式为默认
  restoreStyleColorLocal() {
    if (localStorage.getItem('colorstyle_mode_local')) {
      localStorage.setItem('colorstyle_mode', localStorage.getItem('colorstyle_mode_local'));

      localStorage.setItem('colorstyle_bg', localStorage.getItem('colorstyle_bg_local'));
      localStorage.setItem('colorstyle_back', localStorage.getItem('colorstyle_back_local'));
      localStorage.setItem('colorstyle_color', localStorage.getItem('colorstyle_color_local'));
      localStorage.setItem('colorstyle_titleback', localStorage.getItem('colorstyle_titleback_local'));
      localStorage.setItem('colorstyle_titlecolor', localStorage.getItem('colorstyle_titlecolor_local'));
      localStorage.setItem('colorstyle_dialogback', localStorage.getItem('colorstyle_dialogback_local'));
    } else {
      localStorage.removeItem('colorstyle_mode');
      localStorage.removeItem('colorstyle_bg');
      localStorage.removeItem('colorstyle_back');
      localStorage.removeItem('colorstyle_color');
      localStorage.removeItem('colorstyle_titleback');
      localStorage.removeItem('colorstyle_titlecolor');
      localStorage.removeItem('colorstyle_dialogback');
    }
  },

  //通过url参数设置样式
  initUrlStyle(dashboard = null) {
    if (dashboard) {      
      //还原本地样式
      location.restoreStyleColorLocal();

      if (dashboard.layout) {
        //读取报表刷新
        if (!!dashboard.layout.refresh && parseInt(dashboard.layout.refresh)>0 && !window.location.search.includes("refresh")) {
          location.setSearch({ refresh: parseInt(dashboard.layout.refresh) }, true);
        }
        
        //读取报表样式
        let colorStyle = dashboard.layout.colorStyleMode;
        if (!!colorStyle) {
          if (dashboard.layout.isHoldStyle || !localStorage.getItem('colorstyle_mode_local')) location.initStyleColor(colorStyle);
        }

        //报表滚动条
        document.documentElement.style.overflowY = !dashboard.layout.isHideScroll ? 'visible' : 'hidden';    
        document.documentElement.style.overflowX = !dashboard.layout.isHideScroll ? 'visible' : 'hidden';    

        if (!!dashboard.layout.isFullScreen) {
          var isFullscreen = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
          if (!isFullscreen) {
            var element = document.documentElement;
            var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
            requestMethod.call(element);
          }
        }
      }

      if (!!dashboard.layout.dashboardBg) {
        document.body.style.background = dashboard.layout.dashboardBg;
      } else if (window.location.search.includes("show_portal") || window.location.href.includes("/public/dashboards/")) {
        document.body.style.background = window.location.search.includes("show_portal") ? localStorage.getItem('colorstyle_bg') : "#f6f8f9";
      }

      return;
    }

    if (window.location.search.includes("colorstyle_mode")) {
      let colorStyle = location.search.colorstyle_mode;      
      location.initStyleColorLocal(colorStyle);
      
      if (window.location.search.includes("colorstyle_bg")) 
        localStorage.setItem('colorstyle_bg_local', location.search.colorstyle_bg);
      if (window.location.search.includes("colorstyle_back")) 
        localStorage.setItem('colorstyle_back_local', location.search.colorstyle_back);
      if (window.location.search.includes("colorstyle_color")) 
        localStorage.setItem('colorstyle_color_local', location.search.colorstyle_color);
      if (window.location.search.includes("colorstyle_titleback")) 
        localStorage.setItem('colorstyle_titleback_local', location.search.colorstyle_titleback);
      if (window.location.search.includes("colorstyle_titlecolor")) 
        localStorage.setItem('colorstyle_titlecolor_local', location.search.colorstyle_titlecolor);
      if (window.location.search.includes("colorstyle_dialogback")) 
        localStorage.setItem('colorstyle_dialogback_local', location.search.colorstyle_dialogback);

      //还原本地样式
      location.restoreStyleColorLocal();
      if (window.location.search.includes("show_portal") || window.location.href.includes("/public/dashboards/")) {
        document.body.style.background = window.location.search.includes("show_portal") ? localStorage.getItem('colorstyle_bg') : '#f6f8f9';
      }
    }

    //设置门户轮播
    if (window.location.search.includes("portal_auto")) {
      if (location.search.portal_auto !== 'false')
        localStorage.setItem('portal_auto', true);
      else
        localStorage.removeItem('portal_auto');
    }

      //设置门户标题
    if (window.location.search.includes("portal_hide")) {
      if (location.search.portal_hide !== 'false')
        localStorage.setItem('portal_hide', true);
      else
        localStorage.removeItem('portal_hide');
    }
    
    //设置默认菜单
    if (window.location.search.includes("portal_menu")) 
      localStorage.setItem('portal_menu', location.search.portal_menu);

    //设置默认样式
    if (window.location.search.includes("portal_style")) 
      localStorage.setItem('portal_style',location.search.portal_style);
  },

  //得到url参数形式的样式
  getStyleUrl() {
    if (localStorage.getItem('colorstyle_mode')) {
      var r = "colorstyle_mode=" + localStorage.getItem('colorstyle_mode');

      if (localStorage.getItem('colorstyle_bg')) r = r + "&colorstyle_bg=" + localStorage.getItem('colorstyle_bg');
      if (localStorage.getItem('colorstyle_back')) r = r + "&colorstyle_back=" + localStorage.getItem('colorstyle_back');
      if (localStorage.getItem('colorstyle_color')) r = r + "&colorstyle_color=" + localStorage.getItem('colorstyle_color');
      if (localStorage.getItem('colorstyle_titleback')) r = r + "&colorstyle_titleback=" + localStorage.getItem('colorstyle_titleback');
      if (localStorage.getItem('colorstyle_titlecolor')) r = r + "&colorstyle_titlecolor=" + localStorage.getItem('colorstyle_titlecolor');
      if (localStorage.getItem('colorstyle_dialogback')) r = r + "&colorstyle_dialogback=" + localStorage.getItem('colorstyle_dialogback');
      
      return r;
    }
  },  

  listen(handler) {
    if (isFunction(handler)) {
      return history.listen((unused, action) => handler(location, action));
    } else {
      return () => {};
    }
  },

  confirmChange(handler) {
    if (isFunction(handler)) {
      return history.block(nextLocation => {
        return handler(normalizeLocation(nextLocation), location);
      });
    } else {
      return () => {};
    }
  },

  update(newLocation, replace = false) {
    if (isObject(newLocation)) {
      // remap fields and remove undefined ones
      newLocation = omitBy(
        {
          pathname: newLocation.path,
          search: newLocation.search,
          hash: newLocation.hash,
        },
        isUndefined
      );

      // keep existing fields (!)
      newLocation = extend(
        {
          pathname: location.path,
          search: location.search,
          hash: location.hash,
        },
        newLocation
      );

      // serialize search and keep existing search parameters (!)
      if (isObject(newLocation.search)) {
        newLocation.search = omitBy(extend({}, location.search, newLocation.search), isNil);
        newLocation.search = mapValues(newLocation.search, value => (value === true ? null : value));
        newLocation.search = qs.stringify(newLocation.search);
      }
    }
    if (replace) {
      history.replace(newLocation);
    } else {
      history.push(newLocation);
    }
  },

  url: undefined,

  path: undefined,
  setPath(path, replace = false) {
    location.update({ path }, replace);
  },

  search: undefined,
  setSearch(search, replace = false) {
    location.update({ search }, replace);
  },

  hash: undefined,
  setHash(hash, replace = false) {
    location.update({ hash }, replace);
  },
};

function locationChanged() {
  extend(location, normalizeLocation(history.location));
}

history.listen(locationChanged);
locationChanged(); // init service

export default location;
